// @ts-ignore
import { NativeModules, Platform, PermissionsAndroid } from 'react-native';

const LINKING_ERROR =
  `The package 'react-native-check-permissions' doesn't seem to be linked. Make sure: \n\n` +
  Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
  '- You rebuilt the app after installing the package\n' +
  '- You are not using Expo managed workflow\n';
const PERMISSIONS = Object.freeze({
  READ_CALENDAR: 'android.permission.READ_CALENDAR',
  WRITE_CALENDAR: 'android.permission.WRITE_CALENDAR',
  CAMERA: 'android.permission.CAMERA',
  READ_CONTACTS: 'android.permission.READ_CONTACTS',
  WRITE_CONTACTS: 'android.permission.WRITE_CONTACTS',
  GET_ACCOUNTS: 'android.permission.GET_ACCOUNTS',
  ACCESS_FINE_LOCATION: 'android.permission.ACCESS_FINE_LOCATION',
  ACCESS_COARSE_LOCATION: 'android.permission.ACCESS_COARSE_LOCATION',
  ACCESS_BACKGROUND_LOCATION: 'android.permission.ACCESS_BACKGROUND_LOCATION',
  RECORD_AUDIO: 'android.permission.RECORD_AUDIO',
  READ_PHONE_STATE: 'android.permission.READ_PHONE_STATE',
  CALL_PHONE: 'android.permission.CALL_PHONE',
  READ_CALL_LOG: 'android.permission.READ_CALL_LOG',
  WRITE_CALL_LOG: 'android.permission.WRITE_CALL_LOG',
  ADD_VOICEMAIL: 'com.android.voicemail.permission.ADD_VOICEMAIL',
  USE_SIP: 'android.permission.USE_SIP',
  PROCESS_OUTGOING_CALLS: 'android.permission.PROCESS_OUTGOING_CALLS',
  BODY_SENSORS: 'android.permission.BODY_SENSORS',
  SEND_SMS: 'android.permission.SEND_SMS',
  RECEIVE_SMS: 'android.permission.RECEIVE_SMS',
  READ_SMS: 'android.permission.READ_SMS',
  RECEIVE_WAP_PUSH: 'android.permission.RECEIVE_WAP_PUSH',
  RECEIVE_MMS: 'android.permission.RECEIVE_MMS',
  READ_EXTERNAL_STORAGE: 'android.permission.READ_EXTERNAL_STORAGE',
  WRITE_EXTERNAL_STORAGE: 'android.permission.WRITE_EXTERNAL_STORAGE',
});

const CheckPermissions = NativeModules.CheckPermissions
  ? NativeModules.CheckPermissions
  : new Proxy(
    {},
    {
      get() {
        throw new Error(LINKING_ERROR);
      },
    }
  );

export function openSettings(): Promise<Number> {
  return CheckPermissions.openSettings();
}

function checkPermission(permission: any): Promise<Object> {
  return new Promise((resolve, reject) => {
    PermissionsAndroid.check(permission)
      .then((value) => {
        if (value) resolve({ status: 4 });
        else resolve({ status: 3 });
      })
      .catch((reason) => {
        reject(reason);
      });
  });
}
interface Rationale {
  title: string;
  message: string;
  buttonPositive: string;
  buttonNegative?: string | undefined;
  buttonNeutral?: string | undefined;
}

function requestPermission(permission: any, rationale?: Rationale): Promise<Object> {
  return new Promise((resolve, reject) => {
    PermissionsAndroid.request(permission, rationale)
      .then((value) => {
        if (value === 'granted') resolve({ status: 4 });
        else resolve({ status: 3 });
      })
      .catch((reason) => {
        reject(reason);
      });
  });
}

function unsupportedAPIHandle(): Promise<Object> {
  return new Promise((resolve, _reject) => {
    resolve({ status: 4 });
  });
}

export function checkMicrophone(): Promise<Object> {
  return checkPermission(PERMISSIONS.RECORD_AUDIO);
}

export function requestMicrophone(rationale?: Rationale): Promise<Object> {
  return requestPermission(PERMISSIONS.RECORD_AUDIO, rationale);
}
export function checkReadCalendar(): Promise<Object> {
  return checkPermission(PERMISSIONS.READ_CALENDAR);
}

export function requestReadCalendar(rationale?: Rationale): Promise<Object> {
  return requestPermission(PERMISSIONS.READ_CALENDAR, rationale);
}
export function checkWriteCalendar(): Promise<Object> {
  return checkPermission(PERMISSIONS.WRITE_CALENDAR);
}

export function requestWriteCalendar(rationale?: Rationale): Promise<Object> {
  return requestPermission(PERMISSIONS.WRITE_CALENDAR, rationale);
}
export function checkCamera(): Promise<Object> {
  return checkPermission(PERMISSIONS.CAMERA);
}

export function requestCamera(rationale?: Rationale): Promise<Object> {
  return requestPermission(PERMISSIONS.CAMERA, rationale);
}

export function checkPhotoLibrary(): Promise<Object> {
  return unsupportedAPIHandle();
}

export function requestPhotoLibrary(rationale?: Rationale): Promise<Object> {
  return requestPermission(PERMISSIONS.WRITE_EXTERNAL_STORAGE, rationale);
}

export function openLimitedPhotoLibraryPicker(): Promise<Object> {
  return unsupportedAPIHandle();
}

export function requestPhotoLibraryAddOnly(): Promise<Object> {
  return unsupportedAPIHandle();
}

export function checkPhotoLibraryAddOnly(): Promise<Object> {
  return unsupportedAPIHandle();
}

export function checkMediaLibrary(): Promise<Object> {
  return unsupportedAPIHandle();
}

export function requestMediaLibrary(): Promise<Object> {
  return unsupportedAPIHandle();
}

export function checkCoreLocation(): Promise<Object> {
  return checkPermission(PERMISSIONS.ACCESS_FINE_LOCATION);
}

export function requestCoreLocation(rationale?: Rationale): Promise<Object> {
  return requestPermission(PERMISSIONS.ACCESS_FINE_LOCATION, rationale);
}

export function checkBluetooth(): Promise<Object> {
  return new Promise<Object>((resolve, _reject) => {
    resolve({ status: 4 });
  });
}

export function requestBluetooth(): Promise<Object> {
  return new Promise<Object>((resolve, _reject) => {
    resolve({ status: 4 });
  });
}

export function multiply(a: number, b: number): Promise<number> {
  return CheckPermissions.multiply(a, b);
}
